/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.rpc.saas;

import cn.hutool.crypto.SecureUtil;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.DateUtils;
import com.je.common.base.util.JEUUID;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.rpc.setting.MetaSystemSettingRpcService;
import com.je.rbac.cache.AccountPermissionCache;
import com.je.rbac.exception.AccountException;
import com.je.rbac.service.IconType;
import org.apache.servicecomb.provider.pojo.RpcSchema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;

@RpcSchema(schemaId = "rbacTenantInstallRpcService")
public class TenantInstallRpcServiceImpl implements RbacTenantInstallRpcService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private MetaSystemSettingRpcService metaSystemSettingRpcService;
    @Autowired
    private AccountPermissionCache accountPermissionCache;

    @Override
    @Transactional
    public void installTenantInfo(DynaBean tenantBean) {
        //公司
        DynaBean companyBean = metaService.selectOne("JE_RBAC_COMPANY", ConditionsWrapper.builder()
                .eq("COMPANY_CODE", tenantBean.getStr("TENANT_CODE"))
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        String companyId = null;
        boolean needCreateCompany = false;
        if (companyBean != null) {
            companyId = companyBean.getStr("JE_RBAC_COMPANY_ID");
        } else {
            companyId = JEUUID.uuid();
            needCreateCompany = true;
        }

        //部门
        DynaBean departmentBean = metaService.selectOne("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder()
                .eq("DEPARTMENT_CODE", "SYS-" + tenantBean.getStr("TENANT_CODE"))
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        String departmentId;
        boolean needCreateDepartment = false;
        if (departmentBean != null) {
            departmentId = departmentBean.getStr("JE_RBAC_DEPARTMENT_ID");
        } else {
            departmentId = JEUUID.uuid();
            needCreateDepartment = true;
        }

        //部门人员
        DynaBean userBean = metaService.selectOne("JE_RBAC_USER", ConditionsWrapper.builder()
                .eq("USER_CODE", tenantBean.getStr("TENANT_LXRDH"))
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        String userId;
        if (userBean == null) {
            userId = JEUUID.uuid();
            userBean = new DynaBean("JE_RBAC_USER", true);
            userBean.set("JE_RBAC_USER_ID", userId);
            userBean.set("USER_NAME", tenantBean.getStr("TENANT_ZHLXR"));
            userBean.set("USER_CODE", tenantBean.getStr("TENANT_LXRDH"));
            userBean.set("USER_PHONE", tenantBean.getStr("TENANT_LXRDH"));
            userBean.set("SY_ORG_ID", "systemdepartment");
            userBean.set("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"));
            userBean.set("SY_TENANT_NAME", tenantBean.getStr("TENANT_NAME"));
            userBean.set("SY_COMPANY_ID", companyId);
            userBean.set("SY_COMPANY_CODE", tenantBean.getStr("TENANT_CODE"));
            userBean.set("SY_COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            userBean.set("SY_GROUP_COMPANY_ID", companyId);
            userBean.set("SY_GROUP_COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            userBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
            metaService.insert(userBean);
        } else {
            userId = userBean.getStr("JE_RBAC_USER_ID");
        }


        if (needCreateCompany) {
            companyId = JEUUID.uuid();
            companyBean = new DynaBean("JE_RBAC_COMPANY", true);
            companyBean.set("JE_RBAC_COMPANY_ID", companyId);
            companyBean.set("COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            companyBean.set("COMPANY_CODE", tenantBean.getStr("TENANT_CODE"));
            companyBean.set("COMPANY_MANAGER_ID", userId);
            companyBean.set("COMPANY_MANAGER_NAME", tenantBean.getStr("TENANT_ZHLXR"));
            companyBean.set("COMPANY_MAJOR_ID", userId);
            companyBean.set("COMPANY_MAJOR_NAME", tenantBean.getStr("TENANT_ZHLXR"));
            companyBean.set("COMPANY_LEVEL_CODE", "GROUP_COMPANY");
            companyBean.set("COMPANY_LEVEL_NAME", "集团公司");
            companyBean.set("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"));
            companyBean.set("SY_TENANT_NAME", tenantBean.getStr("TENANT_NAME"));
            companyBean.set("COMPANY_REMARK", tenantBean.getStr("TENANT_REMARK"));
            companyBean.set("COMPANY_ICON", IconType.TCONTYPE_GROUP.getVal());
            companyBean.set("SY_PARENT", "ROOT");
            companyBean.set("SY_PARENTPATH", "/ROOT");
            companyBean.set("SY_LAYER", 1);
            companyBean.set("SY_STATUS", "1");
            companyBean.set("SY_NODETYPE", "LEAF");
            companyBean.set("SY_PATH", "/ROOT/" + companyId);
            companyBean.set("SY_TREEORDERINDEX", "000001000001");
            commonService.buildModelCreateInfo(companyBean);
            metaService.insert(companyBean);
        }

        if (needCreateDepartment) {
            departmentId = JEUUID.uuid();
            departmentBean = new DynaBean("JE_RBAC_DEPARTMENT", false);
            departmentBean.set("JE_RBAC_DEPARTMENT_ID", departmentId);
            departmentBean.set("DEPARTMENT_NAME", "系统管理部");
            departmentBean.set("DEPARTMENT_SIMPLE_NAME", "系统管理部");
            departmentBean.set("DEPARTMENT_CODE", "SYS-" + tenantBean.getStr("TENANT_CODE"));
            departmentBean.set("DEPARTMENT_LEVEL_CODE", "DEPT");
            departmentBean.set("DEPARTMENT_LEVEL_NAME", "部门");
            departmentBean.set("DEPARTMENT_ICON", IconType.TCONTYPE_DEPART.getVal());
            departmentBean.set("SY_COMPANY_ID", companyId);
            departmentBean.set("SY_COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            departmentBean.set("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"));
            departmentBean.set("SY_TENANT_NAME", tenantBean.getStr("TENANT_NAME"));

            departmentBean.set("DEPARTMENT_MAJOR_ID", userId);
            departmentBean.set("DEPARTMENT_MAJOR_NAME", tenantBean.getStr("TENANT_ZHLXR"));
            departmentBean.set("DEPARTMENT_FUNC_DESC", "系统管理部");
            departmentBean.set("DEPARTMENT_REMARK", "系统自动创建，系统管理");
            departmentBean.set("SY_COMPANY_ID", companyId);
            departmentBean.set("SY_COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            departmentBean.set("SY_GROUP_COMPANY_ID", companyId);
            departmentBean.set("SY_GROUP_COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            departmentBean.set("SY_ORG_ID", "systemdepartment");
            departmentBean.set("SY_PARENT", "ROOT");
            departmentBean.set("SY_PARENTPATH", "/ROOT");
            departmentBean.set("SY_LAYER", 1);
            departmentBean.set("SY_STATUS", "1");
            departmentBean.set("SY_NODETYPE", "LEAF");
            departmentBean.set("SY_PATH", "/ROOT/" + companyId + "/" + departmentId);
            departmentBean.set("SY_TREEORDERINDEX", "000001000001000001");
            departmentBean.set("PARENT_NODETYPE", "company");
            departmentBean.set("DEPARTMENT_PARENT", companyId);
            commonService.buildModelCreateInfo(departmentBean);
            metaService.insert(departmentBean);
        }

        //部门人员关联关系
        DynaBean departmentUserBean = metaService.selectOne("JE_RBAC_DEPTUSER", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"))
                .eq("JE_RBAC_USER_ID", userBean)
                .eq("JE_RBAC_DEPARTMENT_ID", departmentId));
        if (departmentUserBean == null) {
            departmentUserBean = new DynaBean("JE_RBAC_DEPTUSER", false);
            departmentUserBean.set("JE_RBAC_DEPARTMENT_ID", departmentId);
            departmentUserBean.set("JE_RBAC_USER_ID", userId);
            departmentUserBean.set("DEPTUSER_MAIN_CODE", "1");
            departmentUserBean.set("DEPTUSER_MAIN_NAME", "是");
            departmentUserBean.set("SY_COMPANY_ID", companyId);
            departmentUserBean.set("SY_COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            departmentUserBean.set("SY_GROUP_COMPANY_ID", companyId);
            departmentUserBean.set("SY_GROUP_COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            departmentUserBean.set("DEPTUSER_SFZG_CODE", "1");
            departmentUserBean.set("DEPTUSER_SFZG_NAME", "是");
            departmentUserBean.set("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"));
            departmentUserBean.set("SY_TENANT_NAME", tenantBean.getStr("TENANT_NAME"));
            commonService.buildModelCreateInfo(departmentUserBean);
            metaService.insert(departmentUserBean);
        }

        String defaultPassword = metaSystemSettingRpcService.requireSettingValue("JE_SYS_PASSWORD");
        if (Strings.isNullOrEmpty(defaultPassword)) {
            throw new AccountException("系统设置默认密码为空！");
        }

        //创建账号
        DynaBean accountBean = metaService.selectOne("JE_RBAC_ACCOUNT", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"))
                .and(inWrapper -> {
                    inWrapper.eq("ACCOUNT_CODE", tenantBean.getStr("TENANT_LXRDH"))
                            .or()
                            .eq("ACCOUNT_PHONE", tenantBean.getStr("TENANT_LXRDH"));
                }));
        String accountId;
        if (accountBean == null) {
            accountId = JEUUID.uuid();
            accountBean = new DynaBean("JE_RBAC_ACCOUNT", true);
            accountBean.set("JE_RBAC_ACCOUNT_ID", accountId);
            accountBean.set("ACCOUNT_NAME", tenantBean.getStr("TENANT_ZHLXR"));
            accountBean.set("ACCOUNT_CODE", tenantBean.getStr("TENANT_LXRDH"));
            accountBean.set("ACCOUNT_OPENID", JEUUID.uuid());
            accountBean.set("ACCOUNT_PASSWORD", SecureUtil.md5(defaultPassword));
            accountBean.set("ACCOUNT_PHONE", tenantBean.getStr("TENANT_LXRDH"));
            accountBean.set("USER_STATUS", "1");
            accountBean.set("ACCOUNT_LOCKED_STATUS", "1");
            accountBean.set("SY_STATUS", "1");
            accountBean.set("ACCOUNT_AVATAR", "");
            accountBean.set("USER_ASSOCIATION_ID", userId);
            accountBean.set("ACCOUNT_REMARK", "SAAS租户创建");
            accountBean.set("SY_ORG_ID", "systemdepartment");
            accountBean.set("SY_ORG_NAME", "部门机构");
            accountBean.set("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"));
            accountBean.set("SY_TENANT_NAME", tenantBean.getStr("TENANT_NAME"));
            commonService.buildModelCreateInfo(accountBean);
            metaService.insert(accountBean);
        } else {
            accountId = accountBean.getStr("JE_RBAC_ACCOUNT_ID");
        }

        DynaBean accountDeptBean = metaService.selectOne("JE_RBAC_ACCOUNTDEPT", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"))
                .eq("ACCOUNTDEPT_ACCOUNT_ID", accountId).eq("ACCOUNTDEPT_DEPT_ID", departmentId));
        if (accountDeptBean == null) {
            accountDeptBean = new DynaBean("JE_RBAC_ACCOUNTDEPT", false);
            accountDeptBean.set("ACCOUNTDEPT_ACCOUNT_ID", accountId);
            accountDeptBean.set("ACCOUNTDEPT_DEPT_ID", departmentId);
            accountDeptBean.set("SY_COMPANY_ID", companyId);
            accountDeptBean.set("SY_COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            accountDeptBean.set("SY_GROUP_COMPANY_ID", companyId);
            accountDeptBean.set("SY_GROUP_COMPANY_NAME", tenantBean.getStr("TENANT_NAME"));
            accountDeptBean.set("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"));
            accountDeptBean.set("SY_TENANT_NAME", tenantBean.getStr("TENANT_NAME"));
            metaService.insert(accountDeptBean);
        }

        accountPermissionCache.clear(tenantBean.getStr("JE_SAAS_TENANT_ID"));
    }

    @Override
    @Transactional
    public void uninstallTenantInfo(DynaBean tenantBean) {
        metaService.delete("JE_RBAC_ACCOUNTDEPT", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        metaService.delete("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        metaService.delete("JE_RBAC_ACCOUNT", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        metaService.delete("JE_RBAC_DEPTUSER", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        metaService.delete("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        metaService.delete("JE_RBAC_USER", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        metaService.delete("JE_RBAC_COMPANY", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        metaService.delete("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        metaService.delete("JE_RBAC_SUPPLIER", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        accountPermissionCache.clear(tenantBean.getStr("JE_SAAS_TENANT_ID"));
    }

    @Override
    @Transactional
    public Map<String, String> installRbacResource(DynaBean tenantBean, DynaBean product, Map<String, List<DynaBean>> resourceMap) {
        List<DynaBean> roleBeanList = resourceMap.get("role");
        return installRoleList(tenantBean, product, roleBeanList);
    }

    @Override
    @Transactional
    public void uninstallRbacResource(DynaBean tenantBean, DynaBean product, Map<String, List<DynaBean>> resourceMap) {
        List<DynaBean> roleBeanList = resourceMap.get("role");
        List<String> roleIdList = new ArrayList<>();
        for (DynaBean eachRoleBean : roleBeanList) {
            roleIdList.add(eachRoleBean.getStr("PROZY_ZY_ID"));
        }
        metaService.delete("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"))
                .eq("ROLE_SAAS_PID", product.getStr("JE_SAAS_PRODUCT_ID"))
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        metaService.delete("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"))
                .in("ACCOUNTROLE_ROLE_ID", roleIdList));
        accountPermissionCache.clear(tenantBean.getStr("JE_SAAS_TENANT_ID"));
    }

    private Map<String, String> installRoleList(DynaBean tenantBean, DynaBean product, List<DynaBean> configRoleBeanList) {
        if (configRoleBeanList == null || configRoleBeanList.isEmpty()) {
            return null;
        }

        List<String> roleIdList = new ArrayList<>();
        for (DynaBean eachRoleBean : configRoleBeanList) {
            roleIdList.add(eachRoleBean.getStr("PROZY_ZY_ID"));
        }

        List<DynaBean> realRoleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .in("JE_RBAC_ROLE_ID", roleIdList));

        List<JSONTreeNode> rootRoleNodeList = findRootRole(realRoleBeanList);
        for (JSONTreeNode eachRootNode : rootRoleNodeList) {
            eachRootNode.setParent("ROOT");
            eachRootNode.setNodePath("/ROOT/" + eachRootNode.getId());
            eachRootNode.getBean().put("SY_PARENT", "ROOT");
            eachRootNode.getBean().put("SY_PAHT", "/ROOT/" + eachRootNode.getId());
            eachRootNode.getBean().put("SY_PARENT_PATH", "/ROOT");
            eachRootNode.getBean().put("SY_LAYER", 1);
            buildRoleTree(eachRootNode, realRoleBeanList);
        }

        Map<String, String> oldNewRoleIdMap = new HashMap<>();
        List<DynaBean> newRoleList = new ArrayList<>();
        for (JSONTreeNode eachRootNode : rootRoleNodeList) {
            buildNewRoleList(null, eachRootNode, newRoleList, oldNewRoleIdMap);
        }

        DynaBean userBean = metaService.selectOne("JE_RBAC_VDEPTUSER", ConditionsWrapper.builder()
                .eq("USER_CODE", tenantBean.getStr("TENANT_LXRDH"))
                .eq("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID")));
        int userOrderCount;
        for (DynaBean eachRoleBean : newRoleList) {
            eachRoleBean.set("ROLE_SAAS_PID", product.getStr("JE_SAAS_PRODUCT_ID"));
            eachRoleBean.set("SY_TENANT_ID", tenantBean.getStr("JE_SAAS_TENANT_ID"));
            eachRoleBean.set("SY_TENANT_NAME", tenantBean.getStr("TENANT_NAME"));
            commonService.buildModelCreateInfo(eachRoleBean);
            metaService.insert(eachRoleBean);
            userOrderCount = 0;
            List<Map<String, Object>> userOrderList = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) AS MAX_COUNT FROM JE_RBAC_ACCOUNTROLE WHERE ACCOUNTROLE_ROLE_ID={0}", eachRoleBean.getStr("JE_RBAC_ROLE_ID"));
            if (userOrderList.size() > 0) {
                userOrderCount = Integer.valueOf(userOrderList.get(0).get("MAX_COUNT").toString());
            }
            importAccountByUsers(tenantBean.getStr("JE_SAAS_TENANT_ID"), tenantBean.getStr("TENANT_NAME"), eachRoleBean.getStr("JE_RBAC_ROLE_ID"),
                    userBean.getStr("JE_RBAC_DEPARTMENT_ID"),
                    userBean.getStr("JE_RBAC_USER_ID"), userOrderCount + "");
        }
        accountPermissionCache.clear(tenantBean.getStr("JE_SAAS_TENANT_ID"));
        return oldNewRoleIdMap;
    }

    public void importAccountByUsers(String tenantId, String tenantName, String roleId, String departmentId, String userIds, String sysOrderIndex) throws AccountException {
        List<String> userIdList = Splitter.on(",").splitToList(userIds);
        List<DynaBean> deptUserBeanList = metaService.select("JE_RBAC_VDEPTUSER", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantId)
                .eq("JE_RBAC_DEPARTMENT_ID", departmentId)
                .in("JE_RBAC_USER_ID", userIdList));

        if (deptUserBeanList == null || deptUserBeanList.isEmpty()) {
            throw new AccountException("不存在的部门人员！");
        }

        List<DynaBean> accountBeanList = metaService.select("JE_RBAC_ACCOUNT", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantId)
                .in("USER_ASSOCIATION_ID", userIdList));
        List<String> accountIdList = new ArrayList<>();
        Map<String, DynaBean> hasAccountMap = new HashMap<>();
        for (DynaBean eachAccountBean : accountBeanList) {
            hasAccountMap.put(eachAccountBean.getStr("USER_ASSOCIATION_ID"), eachAccountBean);
            accountIdList.add(eachAccountBean.getStr("JE_RBAC_ACCOUNT_ID"));
        }

        String defaultPassword = metaSystemSettingRpcService.requireSettingValue("JE_SYS_PASSWORD");
        if (Strings.isNullOrEmpty(defaultPassword)) {
            throw new AccountException("系统设置默认密码为空！");
        }

        DynaBean departmentBean = metaService.selectOne("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantId)
                .eq("JE_RBAC_DEPARTMENT_ID", departmentId));
        if (departmentBean == null) {
            throw new AccountException("不存在的部门！");
        }

        DynaBean roleBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantId)
                .eq("JE_RBAC_ROLE_ID", roleId));
        if (roleBean == null) {
            throw new AccountException("不存在的角色！");
        }

        List<DynaBean> accountDeptRoleBeanList = metaService.select("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantId)
                .eq("ACCOUNTROLE_DEPT_ID", departmentId)
                .eq("ACCOUNTROLE_ROLE_ID", roleId)
                .in("ACCOUNTROLE_ACCOUNT_ID", accountIdList));

        DynaBean orgBean = metaService.selectOne("JE_RBAC_ORG", ConditionsWrapper.builder()
                .eq("JE_RBAC_ORG_ID", departmentBean.getStr("SY_ORG_ID")));

        String accountId;
        for (DynaBean eachUserBean : deptUserBeanList) {
            if (!hasAccountMap.containsKey(eachUserBean.getStr("JE_RBAC_USER_ID"))) {
                accountId = JEUUID.uuid();
                DynaBean accountBean = new DynaBean("JE_RBAC_ACCOUNT", true);
                accountBean.set("JE_RBAC_ACCOUNT_ID", accountId);
                accountBean.set("ACCOUNT_NAME", eachUserBean.getStr("USER_NAME"));
                accountBean.set("ACCOUNT_CODE", eachUserBean.getStr("USER_CODE"));
                accountBean.set("ACCOUNT_OPENID", JEUUID.uuid());
                accountBean.set("ACCOUNT_PASSWORD", SecureUtil.md5(defaultPassword));
                accountBean.set("ACCOUNT_PHONE", eachUserBean.getStr("USER_PHONE"));
                accountBean.set("ACCOUNT_MAIL", eachUserBean.getStr("USER_MAIL"));
                accountBean.set("ACCOUNT_SEX", eachUserBean.getStr("USER_SEX_CODE"));
                accountBean.set("ACCOUNT_AVATAR", eachUserBean.getStr("USER_AVATAR"));
                accountBean.set("USER_ASSOCIATION_ID", eachUserBean.getStr("JE_RBAC_USER_ID"));
                accountBean.set("ACCOUNT_REMARK", "通过部门人员创建！");
                accountBean.set("SY_ORG_ID", orgBean.getStr("JE_RBAC_ORG_ID"));
                accountBean.set("SY_ORG_NAME", orgBean.getStr("ORG_NAME"));
                accountBean.set("SY_STATUS", eachUserBean.getStr("SY_STATUS"));
                accountBean.set("USER_STATUS", eachUserBean.getStr("USER_EMPLOYEE_STATUS"));
                accountBean.set("ACCOUNT_LOCKED_STATUS", "1");
                accountBean.set("SY_TENANT_ID", tenantId);
                accountBean.set("SY_TENANT_NAME", tenantName);
                commonService.buildModelCreateInfo(accountBean);
                metaService.insert(accountBean);
            } else {
                accountId = hasAccountMap.get(eachUserBean.getStr("JE_RBAC_USER_ID")).getStr("JE_RBAC_ACCOUNT_ID");
            }

            DynaBean accountDeptBean = metaService.selectOne("JE_RBAC_ACCOUNTDEPT", ConditionsWrapper.builder()
                    .eq("SY_TENANT_ID", tenantId)
                    .eq("ACCOUNTDEPT_DEPT_ID", departmentId)
                    .eq("ACCOUNTDEPT_ACCOUNT_ID", accountId));
            if (accountDeptBean == null) {
                accountDeptBean = new DynaBean("JE_RBAC_ACCOUNTDEPT", false);
                accountDeptBean.set("ACCOUNTDEPT_DEPT_ID", departmentId);
                accountDeptBean.set("ACCOUNTDEPT_DEPT_NAME", departmentBean.getStr("DEPARTMENT_NAME"));
                accountDeptBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
                accountDeptBean.set("ACCOUNTDEPT_ACCOUNT_ID", accountId);
                accountDeptBean.set("SY_COMPANY_ID", departmentBean.getStr("SY_COMPANY_ID"));
                accountDeptBean.set("SY_COMPANY_NAME", departmentBean.getStr("SY_COMPANY_NAME"));
                accountDeptBean.set("SY_GROUP_COMPANY_ID", departmentBean.getStr("SY_GROUP_COMPANY_ID"));
                accountDeptBean.set("SY_GROUP_COMPANY_NAME", departmentBean.getStr("SY_GROUP_COMPANY_NAME"));
                accountDeptBean.set("SY_TENANT_ID", tenantId);
                accountDeptBean.set("SY_TENANT_NAME", tenantName);
                metaService.insert(accountDeptBean);
            }

            if (accountDeptRoleBeanList == null || accountDeptRoleBeanList.isEmpty()) {
                DynaBean accountDeptRoleTempBean = new DynaBean("JE_RBAC_ACCOUNTROLE", false);
                accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_ID", departmentId);
                accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_NAME", departmentBean.getStr("DEPARTMENT_NAME"));
                accountDeptRoleTempBean.set("ACCOUNTROLE_MAIN_CODE", eachUserBean.getStr("DEPTUSER_MAIN_CODE"));
                accountDeptRoleTempBean.set("ACCOUNTROLE_ACCOUNT_ID", accountId);
                accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_ID", roleId);
                accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_NAME", roleBean.getStr("ROLE_NAME"));
                accountDeptRoleTempBean.set("SY_ORDERINDEX", sysOrderIndex);
                accountDeptRoleTempBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
                accountDeptRoleTempBean.set("SY_TENANT_ID", tenantId);
                accountDeptRoleTempBean.set("SY_TENANT_NAME", tenantName);
                metaService.insert(accountDeptRoleTempBean);
            } else {
                for (DynaBean eachAccountDeptRoleBean : accountDeptRoleBeanList) {
                    if (eachAccountDeptRoleBean.getStr("ACCOUNTROLE_DEPT_ID").equals(departmentId)
                            && eachAccountDeptRoleBean.getStr("ACCOUNTROLE_ROLE_ID").equals(roleId)
                            && eachAccountDeptRoleBean.getStr("ACCOUNTROLE_ACCOUNT_ID").equals(accountId)) {
                        //若该角色部门账号数据已存在，检查sysOrderIndex 不一致 则更新
                        if (!(Strings.isNullOrEmpty(eachAccountDeptRoleBean.getStr("SY_ORDERINDEX")) ? "" : eachAccountDeptRoleBean.getStr("SY_ORDERINDEX")).equals(sysOrderIndex)) {
                            metaService.executeSql("UPDATE JE_RBAC_ACCOUNTROLE SET SY_ORDERINDEX={0} WHERE ACCOUNTROLE_ROLE_ID={1} AND ACCOUNTROLE_DEPT_ID={2} AND ACCOUNTROLE_ACCOUNT_ID={3}", sysOrderIndex, roleId, departmentId, accountId);
                        }
                        continue;
                    }
                    DynaBean accountDeptRoleTempBean = new DynaBean("JE_RBAC_ACCOUNTROLE", false);
                    accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_ID", departmentId);
                    accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_NAME", departmentBean.getStr("DEPARTMENT_NAME"));
                    accountDeptRoleTempBean.set("ACCOUNTROLE_ACCOUNT_ID", accountId);
                    accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_ID", roleId);
                    accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_NAME", roleBean.getStr("ROLE_NAME"));
                    accountDeptRoleTempBean.set("SY_ORDERINDEX", sysOrderIndex);
                    accountDeptRoleTempBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
                    accountDeptRoleTempBean.set("SY_TENANT_ID", tenantId);
                    accountDeptRoleTempBean.set("SY_TENANT_NAME", tenantName);
                    metaService.insert(accountDeptRoleTempBean);
                }
            }

        }

        List<DynaBean> realUserBeans = metaService.select("JE_RBAC_USER", ConditionsWrapper.builder()
                .eq("SY_TENANT_ID", tenantId)
                .in("JE_RBAC_USER_ID", userIdList));
        for (DynaBean eachUserBean : realUserBeans) {
            if (!Strings.isNullOrEmpty(eachUserBean.getStr("USER_ROLE_ID")) && eachUserBean.getStr("USER_ROLE_ID").indexOf(roleId) != -1) {
                continue;
            }
            if (Strings.isNullOrEmpty(eachUserBean.getStr("USER_ROLE_ID"))) {
                eachUserBean.set("USER_ROLE_ID", roleId);
                eachUserBean.set("USER_ROLE_NAME", roleBean.getStr("ROLE_NAME"));
            } else {
                eachUserBean.set("USER_ROLE_ID", eachUserBean.getStr("USER_ROLE_ID") + "," + roleId);
                eachUserBean.set("USER_ROLE_NAME", eachUserBean.getStr("USER_ROLE_NAME") + "," + roleBean.getStr("ROLE_NAME"));
            }
            metaService.update(eachUserBean);
        }
    }

    /**
     * 构建新的层级树，并形成新的beanList
     *
     * @param parentNode
     * @param eachNode
     * @param newRoleList
     */
    private void buildNewRoleList(JSONTreeNode parentNode, JSONTreeNode eachNode, List<DynaBean> newRoleList, Map<String, String> oldNewRoleIdMap) {
        DynaBean newBean = new DynaBean("JE_RBAC_ROLE", true);
        String newId = JEUUID.uuid();
        oldNewRoleIdMap.put(eachNode.getId(), newId);
        if (parentNode == null) {
            eachNode.setNodePath("/ROOT/" + newId);
            eachNode.getBean().put("SY_PAHT", "/ROOT/" + newId);
            eachNode.getBean().put("SY_PARENT_PATH", "/ROOT");
        } else {
            eachNode.getBean().put("SY_PARENT", parentNode.getId());
            eachNode.getBean().put("SY_PAHT", parentNode.getNodePath() + "/" + eachNode.getId());
            eachNode.getBean().put("SY_PARENT_PATH", parentNode.getNodePath());
        }
        eachNode.getBean().put("ROLE_BASE_ID", eachNode.getId());
        eachNode.getBean().put("ROLE_BASE_NAME", eachNode.getText());
        eachNode.setId(newId);
        eachNode.getBean().put("JE_RBAC_ROLE_ID", newId);
        newBean.setValues((HashMap<String, Object>) eachNode.getBean());
        newBean.set(BeanService.KEY_TABLE_CODE, "JE_RBAC_ROLE");
        newRoleList.add(newBean);
        for (JSONTreeNode eachChildNode : eachNode.getChildren()) {
            buildNewRoleList(eachNode, eachChildNode, newRoleList, oldNewRoleIdMap);
        }
    }

    /**
     * 查找根节点，此根节点应为ROOT下的第一层节点
     *
     * @param roleBeanList
     * @return
     */
    private List<JSONTreeNode> findRootRole(List<DynaBean> roleBeanList) {
        List<JSONTreeNode> rootNodeList = new ArrayList<>();
        List<String> roleIdList = new ArrayList<>();
        for (DynaBean eachRole : roleBeanList) {
            roleIdList.add(eachRole.getStr("JE_RBAC_ROLE_ID"));
        }

        for (DynaBean eachRole : roleBeanList) {
            if (roleIdList.contains(eachRole.getStr("SY_PARENT"))) {
                continue;
            }
            rootNodeList.add(buildNode(eachRole.getValues()));
        }

        return rootNodeList;
    }

    /**
     * 构建树
     *
     * @param parentNode
     * @param roleBeanList
     */
    private void buildRoleTree(JSONTreeNode parentNode, List<DynaBean> roleBeanList) {
        JSONTreeNode eachNode;
        for (DynaBean eachBean : roleBeanList) {
            //如果是父节点
            if (parentNode.getId().equals(eachBean.get("JE_RBAC_ROLE_ID"))) {
                continue;
            }
            //不是父节点
            if (!parentNode.getId().equals(eachBean.get("SY_PARENT"))) {
                continue;
            }
            eachNode = buildNode(eachBean.getValues());
            eachNode.setParent(parentNode.getId());
            eachNode.setNodePath(parentNode.getNodePath() + "/" + eachNode.getId());
            eachNode.getBean().put("SY_PARENT", parentNode.getId());
            eachNode.getBean().put("SY_PAHT", parentNode.getNodePath() + "/" + eachNode.getId());
            eachNode.getBean().put("SY_PARENT_PATH", parentNode.getNodePath());
            eachNode.getBean().put("SY_LAYER", Strings.isNullOrEmpty(parentNode.getLayer()) ? 1 : Integer.valueOf(parentNode.getLayer()) + 1);
            parentNode.getChildren().add(eachNode);
            buildRoleTree(eachNode, roleBeanList);
        }
    }

    private JSONTreeNode buildNode(Map<String, Object> roleBean) {
        JSONTreeNode roleNode = new JSONTreeNode();
        roleNode.setId((String) roleBean.get("JE_RBAC_ROLE_ID"));
        roleNode.setCode((String) roleBean.get("ROLE_CODE"));
        roleNode.setText((String) roleBean.get("ROLE_NAME"));
        roleNode.setParent(roleBean.get("SY_PARENT") == null ? null : (String) roleBean.get("SY_PARENT"));
        roleNode.setBean(roleBean);
        return roleNode;
    }

}
